View Javadoc
1 package org.apache.commons.betwixt.digester; 2 3 /* 4 * ==================================================================== 5 * 6 * The Apache Software License, Version 1.1 7 * 8 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 9 * reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in 20 * the documentation and/or other materials provided with the 21 * distribution. 22 * 23 * 3. The end-user documentation included with the redistribution, if 24 * any, must include the following acknowlegement: 25 * "This product includes software developed by the 26 * Apache Software Foundation (http://www.apache.org/)." 27 * Alternately, this acknowlegement may appear in the software itself, 28 * if and wherever such third-party acknowlegements normally appear. 29 * 30 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 31 * Foundation" must not be used to endorse or promote products derived 32 * from this software without prior written permission. For written 33 * permission, please contact apache@apache.org. 34 * 35 * 5. Products derived from this software may not be called "Apache" 36 * nor may "Apache" appear in their names without prior written 37 * permission of the Apache Group. 38 * 39 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 40 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 42 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 45 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 46 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 47 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 48 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 49 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This software consists of voluntary contributions made by many 54 * individuals on behalf of the Apache Software Foundation. For more 55 * information on the Apache Software Foundation, please see 56 * <http://www.apache.org/>;. 57 * 58 */ 59 60 import java.beans.BeanInfo; 61 import java.beans.Introspector; 62 import java.beans.PropertyDescriptor; 63 64 import org.apache.commons.betwixt.ElementDescriptor; 65 import org.apache.commons.betwixt.XMLBeanInfo; 66 import org.apache.commons.betwixt.expression.ConstantExpression; 67 68 import org.apache.commons.logging.Log; 69 import org.apache.commons.logging.LogFactory; 70 71 import org.xml.sax.Attributes; 72 import org.xml.sax.SAXException; 73 74 /*** 75 * <p><code>ElementRule</code> the digester Rule for parsing 76 * the <element> elements.</p> 77 * 78 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 79 * @version $Id: ElementRule.java,v 1.2 2002/07/01 18:52:21 rdonkin Exp $ 80 */ 81 public class ElementRule extends RuleSupport { 82 83 /*** Logger */ 84 private static final Log log = LogFactory.getLog( ElementRule.class ); 85 86 private ClassLoader classLoader; 87 88 private Class beanClass; 89 90 public ElementRule() { 91 this.classLoader = getClass().getClassLoader(); 92 } 93 94 // Rule interface 95 //------------------------------------------------------------------------- 96 97 /*** 98 * Process the beginning of this element. 99 * 100 * @param attributes The attribute list of this element 101 */ 102 public void begin(Attributes attributes) throws Exception { 103 String name = attributes.getValue( "name" ); 104 105 ElementDescriptor descriptor = new ElementDescriptor(); 106 descriptor.setQualifiedName( name ); 107 descriptor.setLocalName( name ); 108 String uri = attributes.getValue( "uri" ); 109 if ( uri != null ) { 110 descriptor.setURI( uri ); 111 } 112 113 String propertyName = attributes.getValue( "property" ); 114 descriptor.setPropertyName( propertyName ); 115 116 String propertyType = attributes.getValue( "type" ); 117 118 if (log.isTraceEnabled()) { 119 log.trace( 120 "(BEGIN) name=" + name + " uri=" + uri 121 + " property=" + propertyName + " type=" + propertyType); 122 } 123 124 // set the property type using reflection 125 descriptor.setPropertyType( 126 getPropertyType( propertyType, beanClass, propertyName ) 127 ); 128 129 130 if ( propertyName != null && propertyName.length() > 0 ) { 131 configureDescriptor(descriptor); 132 } 133 else { 134 String value = attributes.getValue( "value" ); 135 if ( value != null ) { 136 descriptor.setTextExpression( new ConstantExpression( value ) ); 137 } 138 } 139 140 Object top = digester.peek(); 141 if ( top instanceof XMLBeanInfo ) { 142 XMLBeanInfo beanInfo = (XMLBeanInfo) top; 143 beanInfo.setElementDescriptor( descriptor ); 144 beanClass = beanInfo.getBeanClass(); 145 } 146 else if ( top instanceof ElementDescriptor ) { 147 ElementDescriptor parent = (ElementDescriptor) top; 148 parent.addElementDescriptor( descriptor ); 149 } 150 else { 151 throw new SAXException( "Invalid use of <element>. It should " + 152 "be nested inside <info> or other <element> nodes" ); 153 } 154 155 digester.push(descriptor); 156 } 157 158 159 /*** 160 * Process the end of this element. 161 */ 162 public void end() throws Exception { 163 Object top = digester.pop(); 164 } 165 166 167 // Implementation methods 168 //------------------------------------------------------------------------- 169 protected Class getPropertyType( String propertyClassName, 170 Class beanClass, String propertyName ) { 171 // XXX: should use a ClassLoader to handle 172 // complex class loading situations 173 if ( propertyClassName != null ) { 174 try { 175 Class answer = classLoader.loadClass(propertyClassName); 176 if (answer != null) { 177 if (log.isTraceEnabled()) { 178 log.trace("Used specified type " + answer); 179 } 180 return answer; 181 } 182 } 183 catch (Exception e) { 184 log.warn("Cannot load specified type", e); 185 } 186 } 187 188 PropertyDescriptor descriptor = 189 getPropertyDescriptor( beanClass, propertyName ); 190 if ( descriptor != null ) { 191 return descriptor.getPropertyType(); 192 } 193 194 if (log.isTraceEnabled()) { 195 log.trace("Cannot find property type."); 196 log.trace(" className=" + propertyClassName + " base=" + beanClass + " name=" + propertyName); 197 } 198 return null; 199 } 200 201 /*** Set the Expression and Updater from a bean property name */ 202 protected void configureDescriptor(ElementDescriptor elementDescriptor) { 203 Class beanClass = getBeanClass(); 204 if ( beanClass != null ) { 205 String name = elementDescriptor.getPropertyName(); 206 PropertyDescriptor descriptor = 207 getPropertyDescriptor( beanClass, name ); 208 if ( descriptor != null ) { 209 XMLIntrospectorHelper 210 .configureProperty( elementDescriptor, descriptor ); 211 getProcessedPropertyNameSet().add( name ); 212 } 213 } 214 } 215 216 /*** 217 * Returns the property descriptor for the class and property name. 218 * Note that some caching could be used to improve performance of 219 * this method. Or this method could be added to PropertyUtils. 220 */ 221 protected PropertyDescriptor getPropertyDescriptor( Class beanClass, 222 String propertyName ) { 223 if ( beanClass != null && propertyName != null ) { 224 if (log.isTraceEnabled()) { 225 log.trace("Searching for property " + propertyName + " on " + beanClass); 226 } 227 try { 228 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass ); 229 PropertyDescriptor[] descriptors = 230 beanInfo.getPropertyDescriptors(); 231 if ( descriptors != null ) { 232 for ( int i = 0, size = descriptors.length; i < size; i++ ) { 233 PropertyDescriptor descriptor = descriptors[i]; 234 if ( propertyName.equals( descriptor.getName() ) ) { 235 log.trace("Found matching method."); 236 return descriptor; 237 } 238 } 239 } 240 log.trace("No match found."); 241 return null; 242 } 243 catch (Exception e) { 244 log.warn( "Caught introspection exception", e ); 245 } 246 } 247 return null; 248 } 249 250 }

This page was automatically generated by Maven